import React, { useEffect, useMemo, useRef, useState } from "react";
import { Button, ConfigProvider, Modal, Table, message } from "antd";
import type { TableColumnsType, TableProps } from "antd";
import { Validation } from "@prisma/client";
import styles from "@/styles/Evaluation.module.css";
import EvaluationChart from "@/components/evaluation/evaluationChart";

type TableRowSelection<T> = TableProps<T>["rowSelection"];

const columns: TableColumnsType<Validation> = [
  {
    title: "序号",
    dataIndex: "index",
    key: "index",
    align: "center",
    width: 80,
    render: (text, record, index) => `${index + 1}`,
  },
  {
    title: "类型",
    dataIndex: "virtual",
    key: "virtual",
    align: "center",
    render: (virtual) => (
      <div style={{ color: virtual ? "#389e0d" : "#0958d9" }}>
        {virtual ? "孪生数据" : "真实数据"}
      </div>
    ),
  },
  {
    title: "测试名",
    dataIndex: "name",
    key: "name",
    align: "center",
  },
  {
    title: "测试集",
    dataIndex: "group",
    key: "group",
    align: "center",
    filters: (() => {
      const arr = [];
      arr.push({ text: "test1000", value: "test1000" });
      for (let i = 1; i <= 10; i++) {
        arr.push({ text: `test${i}`, value: `test${i}` });
      }
      return arr;
    })(),
    onFilter: (value, record) => record.group === value,
  },
  {
    title: "干扰(%)",
    dataIndex: "noise",
    key: "noise",
    align: "center",
    sorter: (a, b) => a.noise - b.noise,
  },
  {
    title: "mAP0.5",
    dataIndex: "indicator1",
    key: "indicator1",
    align: "center",
  },
  {
    title: "mAP50_95",
    dataIndex: "indicator2",
    key: "indicator2",
    align: "center",
  },
];
export default function Evaluation() {
  const [records, setRecords] = useState<Validation[]>([]);
  useEffect(() => {
    fetch("http://localhost:3000/api/validation")
      .then((res) => res.json())
      .then((data) => {
        setRecords(data);
      });
  }, []);

  // 数据筛选
  const realData: Validation[] = useMemo(() => {
    return records.filter((item) => !item.virtual);
  }, [records]);
  const virtualData: Validation[] = useMemo(() => {
    return records.filter((item) => item.virtual);
  }, [records]);

  // 表格选择
  const [selectedRealData, setSelectedRealData] = useState<Validation[]>([]);
  const [selectedVirtualData, setSelectedVirtualData] = useState<Validation[]>(
    []
  );
  const realRowSelection: TableRowSelection<Validation> = {
    selections: [
      Table.SELECTION_ALL,
      Table.SELECTION_INVERT,
      Table.SELECTION_NONE,
    ],
    onChange: (newSelectedRowKeys: React.Key[], selectedRows: Validation[]) => {
      setSelectedRealData(selectedRows);
    },
  };

  const virtualRowSelection: TableRowSelection<Validation> = {
    selections: [
      Table.SELECTION_ALL,
      Table.SELECTION_INVERT,
      Table.SELECTION_NONE,
    ],
    onChange: (newSelectedRowKeys: React.Key[], selectRows: Validation[]) => {
      setSelectedVirtualData(selectRows);
    },
  };

  const [isGenModalOpen, setIsGenModalOpen] = useState(false);
  const [isRobModalOpen, setIsRobModalOpen] = useState(false);

  const showGenModal = () => {
    if (selectedRealData.length < 1) {
      message.warning("至少选择一条真实数据测试结果");
    } else if (selectedRealData.length > 1) {
      message.warning("只能选择一条真实数据测试结果");
    } else if (selectedVirtualData.length < 1) {
      message.warning("至少选择一条孪生数据测试结果");
    } else {
      setIsGenModalOpen(true);
    }
  };

  const showRobModal = () => {
    if (selectedRealData.length < 1) {
      message.warning("至少选择一条测试结果");
    } else if (selectedRealData.length !== selectedVirtualData.length) {
      message.warning("真实数据和孪生数据干扰不一致");
    } else {
      setIsRobModalOpen(true);
    }
  };

  const calculateD1 = () => {
    if (selectedRealData.length < 1) return 0;
    const start = selectedRealData[0].indicator1;
    for (let i = 0; i < selectedRealData.length; i++) {
      const now = selectedRealData[i].indicator1;
      if (Math.abs(start - now) / start > 0.2) return selectedRealData[i].noise;
    }
    return selectedRealData[0].noise;
  };
  const calculateD2 = () => {
    if (selectedVirtualData.length < 1) return 0;
    const start = selectedVirtualData[0].indicator1;
    for (let i = 0; i < selectedVirtualData.length; i++) {
      const now = selectedVirtualData[i].indicator1;
      if (Math.abs(start - now) / start > 0.2)
        return selectedVirtualData[i].noise;
    }
    return selectedVirtualData[0].noise;
  };

  return (
    <ConfigProvider
      theme={{
        components: {
          Table: {
            fontSize: 14,
          },
        },
      }}
    >
      <div className={styles.toolBar}>
        <Button type="primary" onClick={showGenModal}>
          泛化性评估
        </Button>
        <Button type="primary" onClick={showRobModal}>
          鲁棒性评估
        </Button>
      </div>
      <div className={styles.twoCol}>
        <Table
          rowSelection={realRowSelection}
          rowKey={(record) => record.id}
          columns={columns}
          dataSource={realData}
          bordered
          scroll={{ y: 680 }}
        />
        <Table
          rowSelection={virtualRowSelection}
          rowKey={(record) => record.id}
          columns={columns}
          dataSource={virtualData}
          bordered
          scroll={{ y: 680 }}
        />
      </div>
      <Modal
        open={isGenModalOpen}
        onOk={() => setIsGenModalOpen(false)}
        onCancel={() => setIsGenModalOpen(false)}
        width={750}
      >
        <EvaluationChart
          key={"1"}
          type="gen"
          title="mAP0.5"
          realResults={selectedRealData.map((item) => item.indicator1)}
          virtualResults={selectedVirtualData.map((item) => item.indicator1)}
          xAxis={selectedVirtualData.map((item) => item.name)}
        ></EvaluationChart>
        <EvaluationChart
          key={"2"}
          type="gen"
          title="mAP50_95"
          realResults={selectedRealData.map((item) => item.indicator2)}
          virtualResults={selectedVirtualData.map((item) => item.indicator2)}
          xAxis={selectedVirtualData.map((item) => item.name)}
        ></EvaluationChart>
      </Modal>
      <Modal
        open={isRobModalOpen}
        onOk={() => setIsRobModalOpen(false)}
        onCancel={() => setIsRobModalOpen(false)}
        width={750}
      >
        <EvaluationChart
          type="rob"
          title="mAP0.5"
          realResults={selectedRealData.map((item) => item.indicator1)}
          virtualResults={selectedVirtualData.map((item) => item.indicator1)}
          xAxis={selectedVirtualData.map((item) => item.noise.toString())}
          d1={calculateD1()}
          d2={calculateD2()}
        ></EvaluationChart>
        <div className={styles.indicators}>
          <div>{`干扰强度d1: ${calculateD1()}%`}</div>
          <div>{`干扰强度d2: ${calculateD2()}%`}</div>
          <div>
            {`e:${(
              (Math.abs(calculateD1() - calculateD2()) / calculateD1()) *
              100
            ).toFixed(5)}%`}
          </div>
        </div>
      </Modal>
    </ConfigProvider>
  );
}
